package com.mind.customer.handler.tongwei;

import com.alibaba.fastjson2.JSONArray;
import com.alibaba.fastjson2.JSONObject;
import com.mind.api.vo.OrderDetailResponse;
import com.mind.common.utils.StringUtils;
import com.mind.common.utils.file.FileUtils;
import com.mind.common.utils.file.vo.FileVo;
import com.mind.customer.api.ocr.OCRUtils;
import com.mind.customer.api.oss.OSSUtils;
import com.mind.customer.config.FileConfig;
import com.mind.customer.domain.vo.HandlerData;
import com.mind.customer.domain.vo.TaskResult;
import com.mind.customer.exception.AjObjectNotFoundException;
import com.mind.customer.handler.common.CommonHandler;
import com.mind.customer.mapper.AjBasicDatadditionMapper;
import com.mind.system.domain.AjBasicDataddition;
import com.mind.system.domain.AjTicketTask;
import lombok.extern.log4j.Log4j2;
import org.jetbrains.annotations.NotNull;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import jakarta.annotation.Resource;
import java.io.File;
import java.io.IOException;
import java.lang.reflect.Field;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 发票处理器
 */
@Component
@Log4j2
public class InvoiceHandler {

    @Resource
    private OCRUtils ocrUtils;

    @Resource
    private AjBasicDatadditionMapper basicDatadditionMapper;

    @Resource
    private FileConfig fileConfig;

    @Resource
    private CommonHandler commonHandler;
    @Value("${invoiceLine.specialType:}")
    private String specialTypes;
    @Resource
    private StampHandler stampHandler;

    private String originalInvoiceFieldKey = "发票";
    @Resource
    private OSSUtils ossUtils;

    /**
     * 处理发票数据
     *
     * @param invoiceDetail
     * @return
     */
    public TaskResult handler(AjTicketTask task, OrderDetailResponse.OrderDetailResult invoiceDetail, Map<String, Map<String, Object>> params) throws AjObjectNotFoundException, IOException {
        JSONObject invoiceResult = new JSONObject();
        JSONArray invoiceList = new JSONArray();
        for (OrderDetailResponse.ListObject list : invoiceDetail.getList()) {
            Field[] fields = list.getClass().getDeclaredFields();
            Map<String, Object> info = (Map<String, Object>) list.getInvoiceInfo();
            FileVo fileVo = null;
            String pdfUrl = "";
            if (info.containsKey("invoiceNumber") &&
                    params.containsKey(info.get("invoiceNumber").toString())) {
                Map<String, Object> contentPass = params.get(info.get("invoiceNumber").toString());
                fileVo = (FileVo) contentPass.get("fileVo");
                pdfUrl = contentPass.get("fileUrl").toString();
                Map<String, Object> content = (Map<String, Object>) contentPass.get("content");
                for (String key : content.keySet()) {
                    Object value = content.get(key);
                    if (StringUtils.isNotNull(value) && StringUtils.isNotEmpty(value.toString())) {
                        info.put(key, value);
                    }
                }

            }
            for (Field field : fields) {
                field.setAccessible(true);
                if (!field.getName().equals("invoiceInfo")) {
                    try {
                        if (StringUtils.isNotNull(field.get(list)) && StringUtils.isNotEmpty(field.get(list).toString())) {
                            info.put(field.getName(), field.get(list));
                        }
                    } catch (IllegalAccessException e) {
                        log.error("{}, 发票字段反射获取值，出现异常:", field.getName(), e);
                    }
                }
            }

            try {
                if (StringUtils.isEmpty(pdfUrl)) {
                    pdfUrl = info.get("pdfUrl").toString();
                    if (!FileUtils.getFileExt(pdfUrl).equals("pdf") && info.containsKey("backupUrl")) {
                        if (StringUtils.isNotNull(info.get("backupUrl")) && StringUtils.isNotEmpty(info.get("backupUrl").toString())) {
                            pdfUrl = info.get("backupUrl").toString();
                        }
                    }
                }
                log.info("图片地址：{}", pdfUrl);
                if (fileVo == null) {
                    fileVo = FileUtils.download(pdfUrl, fileConfig.getBasePath(), fileConfig.getBucketName(), null);
                    ossUtils.upload(fileVo.getFileName(), fileVo.getFilePath());
                }
                if (fileVo.getFilePath().contains("pdf")) {
                    List<FileVo> fileVos = FileUtils.pdfToImage(new File(fileVo.getFilePath()), fileConfig.getBasePath(), fileConfig.getBucketName());
                    for (FileVo f : fileVos) {
                        ossUtils.upload(f.getFileName(), f.getFilePath());
                    }
                    fileVo.setChildren(fileVos);
                }

            } catch (Exception e) {
                log.error("{} 图片下载出错：", info, e);
            }
            List<AjBasicDataddition> basicDatadditions = basicDatadditionMapper.selectBasicDatadditionList(new AjBasicDataddition() {{
                setInvoiceline(info.get("invoiceLine").toString());
                setQuerytype("SIGNATURE_STAMP");
            }});
            if(basicDatadditions.size()>0) {
                JSONObject stampData = stampHandler.handler(task.getTicketType(), originalInvoiceFieldKey, originalInvoiceFieldKey, fileVo, task);
                if (stampData != null) {
                    info.putAll(stampData);
                }
            }
//            String invoiceFieldKey = getInvoiceFieldKey(info.get("invoiceLine").toString());
            // 处理发票特殊信息
            info.put("fileVo", fileVo);
            JSONArray result = commonHandler.handleData(new HandlerData() {{
                setTickCate(originalInvoiceFieldKey);
                setTicketType(task.getTicketType());
                setOriginalData(new JSONArray(info));
            }}).getResult();
            // 拼装发票的种类
            if (result != null && result.size() > 0) {
                if (!invoiceResult.containsKey(originalInvoiceFieldKey)) {
                    invoiceResult.put(originalInvoiceFieldKey, new JSONArray());
                }
                invoiceResult.getJSONArray(originalInvoiceFieldKey).add(result.getJSONObject(0));
            }

        }

        //自动处理需要OCR识别的字段并合并进去
        JSONObject invoiceFinalResult;
        try {
            invoiceFinalResult = getOCRInvoiceResult(invoiceResult, task);
        }catch (Exception e){
            log.error("OCR识别OCR识别的字段并合并：", e);
            invoiceFinalResult = invoiceResult;
        }


        JSONObject finalInvoiceFinalResult = invoiceFinalResult;
        return new TaskResult() {{
            setStatus(1);
            setOriginalData(new HashMap<String, Object>() {{
                put(originalInvoiceFieldKey, invoiceList);
            }});
            setData(finalInvoiceFinalResult);
        }};
    }

    @NotNull
    private JSONObject getOCRInvoiceResult(JSONObject result, AjTicketTask task) throws IOException {
        List<AjBasicDataddition> basicDatadditions = basicDatadditionMapper.selectBasic(new AjBasicDataddition());
        Map<String, Map<String, String>> invoiceLines = new HashMap<>();
        basicDatadditions.stream().filter(basic -> StringUtils.isNotEmpty(basic.getInvoiceline())).forEach(basicDataddition -> {
            Map<String, String> fields = new HashMap<>();
            String value = commonHandler.getMappingValue(basicDataddition.getInvoiceline(), "影像发票种类映射表").toString();
            if (invoiceLines.containsKey(value)) {
                fields = invoiceLines.get(value);
            }
            if (StringUtils.isNotEmpty(basicDataddition.getAttachmentdatafield())) {
                fields.put(basicDataddition.getAttachmentdatafield(), "一般表达为" + basicDataddition.getAttachmentdatafield() + (StringUtils.isNotEmpty(basicDataddition.getCondition()) ? basicDataddition.getCondition() : ""));
            }
            invoiceLines.put(value, fields);
        });
        // 根据配置自动合并需要OCR识别的字段

        JSONObject invoiceResult = result;
        if (!invoiceLines.isEmpty()) {
            for (String key : result.keySet()) {
                JSONArray invoiceList = new JSONArray();
                JSONArray jsonArray = result.getJSONArray(key);
                for (int i = 0; i < jsonArray.size(); i++) {
                    JSONObject jsonObject = jsonArray.getJSONObject(i);
                    if (jsonObject.containsKey("发票种类")) {
                        String invoiceLine = jsonObject.getString("发票种类");
                        if (invoiceLines.containsKey(invoiceLine) && jsonObject.containsKey("fileVo")) {
                            log.info("ocr识别发票种类: " + invoiceLine);
                            FileVo fileVo = jsonObject.getObject("fileVo", FileVo.class);
                            Map<String, String> field = invoiceLines.get(invoiceLine);
                            JSONObject content = ocrUtils.getContent(fileVo, JSONObject.toJSONString(field), task);
                            if (content != null) {
                                for( String k : field.keySet()){
                                    if(content.containsKey(k) && StringUtils.isNotEmpty(content.getString(k))) {
                                        jsonObject.put(k, content.getString(k));
                                    }
                                }
                            }
                            if ("通用发票（纸质）".equals(jsonObject.getString("发票种类"))) {
                                log.info("发票种类为 -> 通用发票（纸质）对象：{}", jsonObject.toString());
                                if (jsonObject.containsKey("通行费(ocr)") && StringUtils.isNotEmpty(jsonObject.getString("通行费(ocr)"))) {
                                    jsonObject.put("发票种类", "车辆通行费");
                                }
                            }
                        }
                    }
                    invoiceList.add(jsonObject);
                }
                invoiceResult.put(key, invoiceList);
            }
        }
        return invoiceResult;
    }

    /**
     * 根据invoiceLine获取发票字段key
     *
     * @return
     */
    public String getInvoiceFieldKey(String invoiceLine) {
        String invoiceFieldKey = "发票";
        if (StringUtils.isNotEmpty(specialTypes) && StringUtils.isNotEmpty(invoiceLine)) {
            String fieldKey = commonHandler.getMappingValue(invoiceLine, "影像发票种类映射表").toString();
            if (Arrays.asList(specialTypes.split(",")).contains(fieldKey)) {
                invoiceFieldKey = fieldKey;
            }
        }
        return invoiceFieldKey;
    }
}
